<?php

namespace App\Http\Controllers\Api\V1;

use App\Enums\ResponseCode;
use App\Enums\SmsEnum;
use App\Exceptions\BusinessException;
use App\Http\Controllers\Api\AbstractApiController;
use App\Http\Resources\UserInfo;
use App\Models\User;
use App\Services\Sms\SmsService;
use App\Services\Umeng\UmengService;
use App\Services\User\UserService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use PHPOpenSourceSaver\JWTAuth\Exceptions\JWTException;
use PHPOpenSourceSaver\JWTAuth\Exceptions\TokenExpiredException;

class AuthController extends AbstractApiController
{
    /**
     * 用户登录
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function login(Request $request): JsonResponse
    {
        $credentials = $request->validate([
            'mobile' => 'required',
            'verify_code' => 'required',
        ], [
            'mobile.required' => '手机号不能为空',
            'verify_code.required' => '验证码不能为空',
        ]);
        //        //验证码验证
        SmsService::verify($credentials['mobile'], $credentials['verify_code'], SmsEnum::LOGIN_CODE);
        $cacheKey = "login-chat{$credentials['mobile']}";
        $lock = Cache::lock($cacheKey, 60);
        if (!$lock->get()) {
            return self::fail('请勿重复提交');
        }
        $userInfo = User::query()->where('mobile', $credentials['mobile'])->first();
        if (!$userInfo) {
            //账号不存在注册新用户
            UserService::createUser(
                mobile: $credentials['mobile']
            );
            $userInfo = User::query()->where('mobile', $credentials['mobile'])->first();
        }
        if ($userInfo->is_lock == 1) {
            $lock->forceRelease();
            return self::error(trans("您的帐号已被锁定"), ResponseCode::LOCKED);
        }
        $token = auth('api')->login($userInfo);
        //获取最后一次的token并加入黑名单
        $lastToken = Cache::get("userLoginToken:{$userInfo->id}");
        if ($lastToken) {
            try {
//                auth('api')->setToken($lastToken)->invalidate();
            } catch (JWTException $e) {
                //因为让一个过期的token再失效，会抛出异常，所以我们捕捉异常，不需要做任何处理
            }
        }
        $expiresIn = auth('api')->factory()->getTTL() * 60000;
        // 将用户token存入缓存
        Cache::set("userLoginToken:{$userInfo->id}", $token, $expiresIn);
        $userInfo->last_at = now();
        $userInfo->last_ip = $request->ip();
        $userInfo->save();
        return self::success(trans("登录成功"), ResponseCode::OK, ['access_token' => $token,
            'token_type' => 'Bearer ',
            'expires_in' => $expiresIn]);
    }

    /**
     * 友盟一键登录
     * @param Request $request
     * @param UmengService $umengService
     * @return JsonResponse
     * @throws BusinessException
     * @throws \App\Exceptions\ApiExceptions
     */
    public function oneclickLogin(Request $request,UmengService $umengService): JsonResponse
    {
        $input = $request->validate([
            'token' => 'required',
        ]);
        $mobile = $umengService->oneclickLogin($input['token']);
        $userInfo = User::query()->where('mobile',$mobile)->first();
        if (!$userInfo) {
            //账号不存在注册新用户
            UserService::createUser(
                mobile: $mobile
            );
            $userInfo = User::query()->where('mobile', $mobile)->first();
        }
        $token = auth('api')->login($userInfo);
        //获取最后一次的token并加入黑名单
        $lastToken = Cache::get("userLoginToken:{$userInfo->id}");
        if ($lastToken) {
            try {
//                auth('api')->setToken($lastToken)->invalidate();
            } catch (JWTException $e) {
                //因为让一个过期的token再失效，会抛出异常，所以我们捕捉异常，不需要做任何处理
            }
        }
        $expiresIn = auth('api')->factory()->getTTL() * 60000;
        // 将用户token存入缓存
        Cache::set("userLoginToken:{$userInfo->id}", $token, $expiresIn);
        $userInfo->last_at = now();
        $userInfo->last_ip = $request->ip();
        $userInfo->save();
        return self::success(trans("登录成功"), ResponseCode::OK, [
            'mobile'=>$userInfo->mobile,
            'access_token' => $token,
            'token_type' => 'Bearer ',
            'expires_in' => $expiresIn]);
    }

    /**
     * @return JsonResponse
     * 登录初始化
     */
    public function loginInit(): JsonResponse
    {
        $url = config('app.h5_url');
        //获取h5的域名
        return self::success(trans("success"), ResponseCode::OK, compact('url'));
    }

    /**
     * Get the authenticated User.
     *
     * @return JsonResponse
     */
    public function me()
    {
        return self::success(trans("success"), ResponseCode::OK, new UserInfo(auth('api')->user()));
    }

    /**
     * Refresh a token.
     *
     * @return JsonResponse
     */
    public function refresh()
    {
        $userInfo = auth('api')->User();
        if (!is_null($userInfo)) {
            //先刷新再拉黑
            $access_token = auth('api')->refresh();
            $expiresIn = auth('api')->factory()->getTTL() * 60;
            //获取最后一次的token并加入黑名单
            $lastToken = Cache::get("userLoginToken:{$userInfo->id}");
            if ($lastToken) {
                try {
                    auth('api')->setToken($lastToken)->invalidate();
                } catch (TokenExpiredException $e) {
                    //因为让一个过期的token再失效，会抛出异常，所以我们捕捉异常，不需要做任何处理
                }
            }
            // 将用户token存入缓存
            Cache::set("userLoginToken:{$userInfo->id}", $access_token, $expiresIn);
            return self::success("success", ResponseCode::OK,
                [
                    'access_token' => $access_token,
                    'token_type' => 'Bearer ',
                    'expires_in' => auth('api')->factory()->getTTL() * 60
                ]
            );
        } else {
            return self::error(trans("exception.Token已失效请重新登录"), ResponseCode::UNAUTHORIZED);
        }
    }

    /**
     * 注销账户
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function unsubscribe(Request $request): JsonResponse
    {
        $credentials = $request->validate([
            'verify_code' => 'required',
        ], [
            'verify_code.required' => '验证码不能为空',
        ]);
        $userInfo = auth('api')->user();

        //验证码验证
        SmsService::verify($userInfo->mobile, $credentials['verify_code'], SmsEnum::WRITE_OFF);
        //验证安全密码
        $userInfo->unsubscribe();
        return self::success(trans("注销成功"));
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return JsonResponse
     */
    public function logout(): JsonResponse
    {
        if (!auth('api')->guest()) {
            auth('api')->logout();
        }
        return self::success(trans("退出登录成功"));
    }

    /**
     * 注册初始化
     * @return JsonResponse
     */
    public function registerInit()
    {
        $result = [
            'agreement' => route('web.article', ['id' => 3]),//用户协议
        ];
        return self::success(trans("success"), ResponseCode::OK, $result);
    }
}
